class Observer {
  constructor(data) {
    this.walk(data);
  }

  // 遍历 data 给每一个属性添加 getter 和 setter
  walk(data) {
    // 判断 data 是否是一个对象
    if (!data || typeof data !== "object") return;

    // 遍历 data 的所有属性
    Object.keys(data).forEach((key) => {
      this.defineReactive(data, key, data[key]);
    });
  }

  defineReactive(obj, key, value) {
    // 每个属性都需要收集依赖
    let dep = new Dep();
    let _this = this;
    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get() {
        // 判断 Dep 是否有一个静态的 target 属性，这个属性是 new Watcher 的时候添加到 Dep 上的
        // new Watcher 的时候，会触发相应属性的 get 的方法，也就是此方法，添加 Watcher
        // 完成 Watcher 的添加后，会在 Watcher 的构造函数中删除 target 属性
        // 这种条件 Watcher 的方式非常巧妙， 666666666666666666666666666
        if (Dep.target) {
          dep.addSub(Dep.target)
        };
        return value;
      },
      set(newValue) {
        if (newValue === value) return;
        // 这里不能用 obj[key] = newValue ,因为 obj[key] 会触发当前的 set 方法造成死循环
        value = newValue;
        // 修改 data 的属性为对象的时候，需要转换为响应式数据
        _this.walk(value);
        // 每次设置属性，触发相应的依赖，通知 watcher 更新视图
        dep.notify(value);
      },
    });

    // 如果 value 是一个对象，递归调用 walk, 处理 value 的属性
    this.walk(value);
  }
}
